﻿using System.Security.Policy;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Web.Security;
using Isaac.Joy.Identity.Module;
using Isaac.Joy.Menu.Module;
using Isaac.Joy.Serialize;
using Isaac.Joy.WebFramework.DtCms.ExtensionObjects;
using Isaac.Joy.WebFramework.DtCms.Models;
using UIShell.OSGi;

namespace Isaac.Joy.WebFramework.DtCms.Controllers
{
    [Permission]
    public class HomeController : Controller
    {
        private IRepository _repository;
        protected IRepository Repository
        {
            get
            {
                return _repository ?? (_repository = BundleRuntime.Instance.GetFirstOrDefaultService<IRepository>());
            }
        }

        public ActionResult Index()
        {
            var viewClass = new FrameworkViewClass
            {
                Menus = new List<IMenu>(),
                QuickMenus = new List<IMenu>()
            };
            if (Activator.BundleContext == null) return View(viewClass);

            var extensions = Activator.BundleContext.GetExtensions("Isaac.Joy.Menu.MenuConfigCreater");
            foreach (var extension in extensions)
            {
                foreach (var item in extension.Data)
                {
                    var creater = XmlSerializable.Deserialize<MenuConfigCreater>(item);
                    var config = System.Activator.CreateInstance(extension.Owner.LoadClass(creater.Type)) as IMenus;
                    if (config != null)
                    {
                        foreach (var menu in FliterMenu(config.Menus, extension.Owner.SymbolicName))
                        {
                            if (!menu.IsLeaf)
                            {
                                viewClass.Menus = AddMenu(viewClass.Menus, menu);
                            }
                            else
                            {
                                viewClass.QuickMenus = viewClass.QuickMenus.Add(menu);
                            }
                        }
                    }
                }
            }

            viewClass.Menus = viewClass.Menus.OrderBy(x => x.Order);
            viewClass.QuickMenus = viewClass.QuickMenus.OrderBy(x => x.Order);

            var extconfig = Activator.BundleContext.GetExtensions("Isaac.Joy.Framework.Config");
            if (extconfig.Count > 0 && extconfig[0].Data.Count > 0)
            {
                var frameworkConfig = XmlSerializable.Deserialize<FrameworkConfig>(extconfig[0].Data[0]);
                viewClass.DefaultActionId = frameworkConfig.DefaultActionId;
            }

            return View(viewClass);
        }

        public ActionResult Welcome()
        {
            return View();
        }

        private IEnumerable<IMenu> AddMenu(IEnumerable<IMenu> targetMenus, IMenu sourceMenu)
        {
            var returnMenus = new List<IMenu>();

            var addsource = true;
            foreach (var targetMenu in targetMenus)
            {
                if (targetMenu.Name != sourceMenu.Name)
                {
                    //var addmenu = new Menu.Module.Menu
                    //{
                    //    Icon = targetMenu.Icon,
                    //    Action = targetMenu.Action,
                    //    Name = targetMenu.Name,
                    //    Order = targetMenu.Order,
                    //    Permission = targetMenu.Permission,
                    //    Menus = (List<Menu.Module.Menu>)targetMenu.Childrens
                    //};
                    returnMenus.Add(targetMenu);
                }
                else
                {
                    addsource = false;
                    var newmenu = new Menu.Module.Menu
                    {
                        Icon = targetMenu.Icon,
                        Action = targetMenu.Action,
                        Name = targetMenu.Name,
                        Order = targetMenu.Order,
                        Permission = targetMenu.Permission,
                        Menus = new List<Menu.Module.Menu>()
                    };

                    var childrens = targetMenu.Childrens.ToList();

                    foreach (var sourcechildren in sourceMenu.Childrens)
                    {
                        childrens = AddMenu(childrens, sourcechildren).ToList();
                    }

                    foreach (var menu in childrens)
                    {
                        newmenu.Add(menu);
                    }
                    returnMenus.Add(newmenu);
                }
            }

            if (addsource)
            {
                returnMenus.Add(sourceMenu);
            }

            return returnMenus;
        }

        private IEnumerable<IMenu> FliterMenu(IEnumerable<IMenu> menus, string symbolicName)
        {
            var returnMenus = new List<IMenu>();

            foreach (var menu in menus)
            {
                if (!string.IsNullOrEmpty(menu.Permission))
                {
                    var permission = Repository.GetPermission(menu.Permission, symbolicName);
                    if(permission == null) continue;

                    var identity = User.Identity as FormsIdentity;
                    if (identity == null) continue;

                    var rolestr = identity.Ticket.UserData;
                    if (!new FlagsValue(rolestr).Enabled(permission.Id)) continue;
                }

                var returnMenu = new Menu.Module.Menu
                {
                    Icon = menu.Icon,
                    Action = menu.Action,
                    Name = menu.Name,
                    Order = menu.Order,
                    Permission = menu.Permission,
                    Menus = new List<Menu.Module.Menu>()
                };

                var fliterMenus = FliterMenu(menu.Childrens, symbolicName);

                foreach (var fliterMenu in fliterMenus)
                {
                    var childrenMenu = new Menu.Module.Menu
                    {
                        Icon = fliterMenu.Icon,
                        Action = fliterMenu.Action,
                        Name = fliterMenu.Name,
                        Order = fliterMenu.Order,
                        Permission = fliterMenu.Permission,
                        Menus = (List<Menu.Module.Menu>)fliterMenu.Childrens
                    };
                    returnMenu.Menus.Add(childrenMenu);
                }

                returnMenus.Add(returnMenu);
            }
            return returnMenus;
        }
    }
}
